//
//  InstallLayerDolphin.cpp
//  client
//
//  Created by sg on 2/17/17.
//
//

#include "InstallLayerDolphin.h"

#include "ui/CocosGUI.h"
#include "AppDelegate.h"
#include "CCLuaEngine.h"
#include "MessageDialog.h"
#include "ConfirmBox.h"
#include "UserDefaultKeys.h"
#include "NodePool.hpp"
#include "CCFactory.h"
#include "custom/Utils.h"

//#include "InfoPlist.h"


#if CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID
#include "JniHelper.h"
#endif

#ifdef USE_MSDK 
#if CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID
#include "SafeAPI.h"
#endif
#endif

USING_NS_CC;
using namespace std;
using namespace cocos2d::ui;
using namespace dragonBones;

#ifdef USE_GCLOUD
using namespace GCloud;
#endif


static std::string s_first_source_file="first_source.png";
static std::string s_EmaQA_str = "Wjyz2DTest";
static std::string s_TXQA_str = "Wjyz2DTencentTest";
static std::string s_TXPre_str = "Wjyz2DTencentPre";

InstallLayerDolphin::InstallLayerDolphin():
InstallLayer()
,_needReloadString(false)
,_newResourceVersion("")
#ifdef USE_GCLOUD
,_dolphinUrl("")
,_dolphinChannelId(-1)
,_isStartUpdate(false)
,_waitNewVersion(false)
,_waitMessageBox(false)
,_shouldStop(false)
,_lastErrorCode(0)
,_lastErrorStage(GCloud::VS_Start)
,_currentUpdateType(GCloud::UpdateInitType_OnlyProgram)
,_curVersionStage(GCloud::VS_Start)
,_needFirstExtract(false)
,_isGrayUpdate(false)
,_grayOpenId(nullptr)
,_grayZoneId(nullptr)
,_dolphin(nullptr)
#endif
{
    //cocos2d::log("====>InstallLayerDolphin ctor _currentUpdateType %d",_currentUpdateType);
}

InstallLayerDolphin::~InstallLayerDolphin()
{
    //cocos2d::log("====>InstallLayerDolphin destroy _currentUpdateType %d ",_currentUpdateType);
}

// on "init" you need to initialize your instance
bool InstallLayerDolphin::init()
{
    bool ret = InstallLayer::init();
#ifdef USE_GCLOUD
    bool _;
    std::string msg = _dolphinInfoString.GetUpdateInfoString(_curVersionStage,_currentUpdateType,_);
    updateStageLabel(msg);
#endif

    AppDelegate::gsdkSetEvent(0, true, "success", false, false);
    return ret;
}


void InstallLayerDolphin::goStart(){
    bool disableHotfix = true;
    Configuration* configuration = Configuration::getInstance();
    const Value& disableValue = configuration->getValue("DisableHotfix");
    if(!disableValue.isNull()){
        disableHotfix = disableValue.asBool();
    }
    
    if(disableHotfix){
        cocos2d::log("===>InstallLayerDolphin   热更新关闭 ");
        scheduleOnce([this](float){
            this->goNext();
        },0,"goNext");
        
        AppDelegate::gsdkSetEvent(1, true, "0-success", false, false);
        AppDelegate::gsdkSetEvent(2, true, "0-success", false, false);
    }else{
#ifdef USE_GCLOUD
        this->initGCloud();
        
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
        std::string phoneName = Application::getInstance()->getPhoneName();
        if (Utils::checkStringIsEndWith(phoneName, s_TXPre_str) || 
                Utils::checkStringIsEndWith(phoneName, s_TXQA_str) || 
                Utils::checkStringIsEndWith(phoneName, s_EmaQA_str))
            _dolphinUrl = configuration->getValue("TestDolphinUpdateUrl").asString();

        cocos2d::log("===>InstallLayerDolphin phoneName %s _dolphinUrl %s", phoneName.c_str(), _dolphinUrl.c_str());
#endif
        if (_dolphinUrl.empty())
            _dolphinUrl = configuration->getValue("DolphinUpdateUrl").asString();

        _dolphinChannelId = configuration->getValue("DolphinChannelId").asInt();
        cocos2d::log("===>InstallLayerDolphin DolphinUpdateUrl %s _dolphinChannelId：%d",_dolphinUrl.c_str(),_dolphinChannelId);
        
        //        _dolphinChannelId = InfoPlist::getInstance()->getDophinChannelId();
        //        _dolphinUrl = InfoPlist::getInstance()->getDophinUpdateUrl().c_str();
        
        bool needFirstExtract = false;
        
        auto userDefault = UserDefault::getInstance();
        if(userDefault->getIntegerForKey(UD_FIRST_EXTRACT,-1)<=0){
            // cocos2d::log("===>InstallLayerDolphin UD_FIRST_EXTRACT = -1");
            // if(FileUtils::getInstance()->isFileExist(s_first_source_file)){
            //     cocos2d::log("===>InstallLayerDolphin s_first_source_file exist");
            //     needFirstExtract = true;
            // }
            needFirstExtract = true;
        }
        
        _needFirstExtract = needFirstExtract;
        
        cocos2d::log("===>InstallLayerDolphin needFirstExtract:%d",needFirstExtract?1:0);
        
        scheduleOnce([this](float){
            this->startUpdateProgram();
        },0,"startUpdateProgram");
        
        scheduleUpdate();
#else
        cocos2d::log("===>InstallLayerDolphin   USE_GCLOUD。没有定义 ");
        scheduleOnce([this](float){
            this->goNext();
        },0,"goNext");
        AppDelegate::gsdkSetEvent(1, true, "0-success", false, false);
        AppDelegate::gsdkSetEvent(2, true, "0-success", false, false);
#endif
    }
}
void InstallLayerDolphin::goExit(){
#ifdef USE_GCLOUD
    uninitDolphin();
    
    cocos2d::log("===>InstallLayerDolphin onExit");
#endif
}

#ifdef USE_GCLOUD

void InstallLayerDolphin::startGrayUpdate(const char * openId, const char * zoneId)
{
    cocos2d::log("===>InstallLayerDolphin openId:%s zoneId:%s", openId, zoneId);
    _isGrayUpdate = true;
    _grayOpenId = openId;
    _grayZoneId = zoneId;
    goStart();
}

void InstallLayerDolphin::initGCloud()
{
    static bool _didInitGCloud = false;
    if(!_didInitGCloud){
        Configuration* configuration = Configuration::getInstance();
        uint64_t appid = (uint64_t)configuration->getValue("GCloudAppID").asDouble();
        std::string appKey = configuration->getValue("GCloudAppKey").asString();
        InitializeInfo info(appid,appKey.c_str());
        GCloud::Result result = IGCloud::GetInstance().Initialize(info);
        cocos2d::log("===>InstallLayerDolphin initGCloud: %s",result.ToString().c_str());
        _didInitGCloud = true;
    }
}

void InstallLayerDolphin::uninitGCloud()
{

}

void InstallLayerDolphin::startUpdate(GCloud::dolphinUpdateInitType type,bool needFirstExtract)
{
    _isStartUpdate = false;
    _waitNewVersion = false;
    _waitMessageBox = false;
    _shouldStop = false;
    _updateSuccess = false;
    _lastErrorCode = kSuccess;
    _lastErrorStage = GCloud::VS_Start;

    uninitDolphin();
    
    this->_dolphin = CreateDolphin();

    GCloud::dolphinInitInfo initInfo;
    initInfo.updateType = type;//更新类型
    initInfo.channelId = _dolphinChannelId;//渠道id,与更新控制台上的渠道分类id对应
    initInfo.isGrayUpdate = _isGrayUpdate;//是否灰度更新

#if COCOS2D_DEBUG >= 1
    initInfo.openDebugLog = true;//是否开启debug日志
    initInfo.openErrorLog = true;//是否开启error日志
#else
    initInfo.openDebugLog = false;//是否开启debug日志
    initInfo.openErrorLog = false;//是否开启error日志
#endif

    std::string appVersion = Application::getInstance()->getAppVersion() + ".0";
    std::string srcVersion = "0.0.0." + Application::getInstance()->getResourceVersion();
    
    std::string updateUrl = _dolphinUrl;
    
    //当前程序版本号, 形式x.x.x.x，x对应一个数字（short长度），属于更新服务控制台上//创建的程序版本号集合，参照下面的版本号说明
    sprintf(initInfo.appVersion, "%s", appVersion.c_str());
    //当前资源版本号, 形式x.x.x.x，x对应一个数字（short长度），属于更新服务控制台上//创建的资源版本号集合，参照下面的版本号说明
    sprintf(initInfo.srcVersion, "%s", srcVersion.c_str());
    //更新环境地址，对应渠道页面下的正式环境地址或预发布环境地址
    sprintf(initInfo.updateUrl, "%s",updateUrl.c_str());

    GCloud::dolphinPathInfo pathInfo;

    std::string curApkPath = Application::getInstance()->getAppPath();
    // std::string dolphinPath = FileUtils::getInstance()->getWritablePath()+"dolphin/";
    std::string updatePath = AppDelegate::getStorePath();
    //当前apk路径,当前正在运行apk的绝对路径
    snprintf(pathInfo.curApkPath, DOLPHIN_PATHLENGTH, "%s",curApkPath.c_str());
    //更新信息存储路径，传入时存在并可写，不要删除修改此目录下的内容
    snprintf(pathInfo.dolphinPath, DOLPHIN_PATHLENGTH, "%s", updatePath.c_str());
    //更新路径，资源存放路径，传入时存在并可写，资源从此目录读取
    snprintf(pathInfo.updatePath, DOLPHIN_PATHLENGTH, "%s", updatePath.c_str());

    GCloud::dolphinGrayInfo grayInfo;
    if (_isGrayUpdate)
    {
        //用户id，例如游戏微信登录的openid或QQ号等
        snprintf(grayInfo.userID, DOLPHIN_USERIDLENGTH, "%s", _grayOpenId);
        //用户区服id, 用户登录到游戏区服对应的id
        snprintf(grayInfo.worldID, DOLPHIN_WORLDIDLENGTH, "%s", _grayZoneId);
    }


    GCloud::dolphinFirstExtractInfo feInfo;
    if(needFirstExtract){
        std::string ifsPath;
        //首包解压文件路径
        auto fileUtils = FileUtils::getInstance();
        
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
        ifsPath = StringUtils::format("apk:/%s?assets/%s",curApkPath.c_str(),s_first_source_file.c_str());
#endif
        
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
        ifsPath = fileUtils->fullPathForFilename(s_first_source_file);
#endif

        snprintf(feInfo.ifsPath, DOLPHIN_PATHLENGTH, "%s", ifsPath.c_str());

        cocos2d::log("===>InstallLayerDolphin ifsPath = %s", ifsPath.c_str());
    }

    cocos2d::log("===>InstallLayerDolphin startUpdate isGrayUpdate %s ", _isGrayUpdate ? "true" : "false");
    cocos2d::log("===>InstallLayerDolphin startUpdate appVersion %s ", appVersion.c_str());
    cocos2d::log("===>InstallLayerDolphin startUpdate srcVersion %s ", srcVersion.c_str());
    cocos2d::log("===>InstallLayerDolphin startUpdate updateUrl %s ", updateUrl.c_str());
    cocos2d::log("===>InstallLayerDolphin startUpdate curApkPath %s ", curApkPath.c_str());
    cocos2d::log("===>InstallLayerDolphin startUpdate dolphinPath %s ", updatePath.c_str());
    cocos2d::log("===>InstallLayerDolphin startUpdate updatePath %s ", updatePath.c_str());
    
    //init初始化参数三grayInfo，可以为NULL,在initInfo.isGrayUpdate为true不能是NULL
    //init初始化参数四feInfo，为NULL时不做首包解压，不为NULL时先解压再更新
    this->_dolphin->Init(&initInfo, &pathInfo, &grayInfo, needFirstExtract?&feInfo:nullptr, this);

    this->_dolphin->CheckAppUpdate();
}

void InstallLayerDolphin::uninitDolphin()
{
    if(this->_dolphin){
        this->_dolphin->Uninit();
        GCloud::ReleaseDolphin(&this->_dolphin);
        this->_dolphin=nullptr;
    }
}

void InstallLayerDolphin::startUpdateProgram()
{
    cocos2d::log("===>InstallLayerDolphin startUpdateProgram");
    _currentUpdateType = GCloud::UpdateInitType_OnlyProgram;
    startUpdate(GCloud::UpdateInitType_OnlyProgram,_needFirstExtract);
    updateStageLabel("准备更新程序");
    updateProgressBar(0);
}

void InstallLayerDolphin::startUpdateResource()
{
    cocos2d::log("===>InstallLayerDolphin startUpdateResource");
    _currentUpdateType = GCloud::UpdateInitType_OnlySource;
    startUpdate(GCloud::UpdateInitType_OnlySource,false);
    updateStageLabel("准备更新游戏资源");
    updateProgressBar(0);
}

void InstallLayerDolphin::continueUpdate()
{
    if (this->_dolphin && _waitNewVersion)
    {
        _waitNewVersion = false;
        cocos2d::log("===>InstallLayerDolphin continueUpdate ContinueUpdate");
        this->_dolphin->ContinueUpdate(true);
    }
    
    cocos2d::log("===>InstallLayerDolphin continueUpdate waitMessageBox %d _currentUpdateType:%d",_waitMessageBox?1:0,_currentUpdateType);
    
    if (_waitMessageBox)
    {
        _waitMessageBox = false;
        if (_currentUpdateType == GCloud::UpdateInitType_OnlyProgram)
        {
            startUpdateProgram();
        }
        else if (_currentUpdateType == GCloud::UpdateInitType_OnlySource)
        {
            startUpdateResource();
        }
        else
        {
            startUpdateProgram();
        }
    }
}

void InstallLayerDolphin::stopUpdate()
{
    if(this->_dolphin){
        _shouldStop = true;
        this->_dolphin->CancelUpdate();
        if(_waitNewVersion){
            _waitNewVersion = false;
            _dolphin->ContinueUpdate(false);
        }
        if (_waitMessageBox)
        {
            _waitMessageBox = false;
        }
        _dolphin->PollCallback();
        uninitDolphin();
    }
    _speedCounter.stopSpeedCounter();
}

void InstallLayerDolphin::update(float dt)
{
    _speedCounter.speedCounter(dt);

    if (_waitNewVersion || _waitMessageBox )
    {
        return ;
    }
    if(this->_dolphin && _lastErrorCode == kSuccess)
    {
        _dolphin->PollCallback();
        if(_updateSuccess)
        {
            _updateSuccess = false;
            if (_currentUpdateType == GCloud::UpdateInitType_OnlyProgram )
            {
                startUpdateResource();
            }
            else
            {
                if (_currentUpdateType == GCloud::UpdateInitType_OnlySource && _newResourceVersion.size()>0)
                {
                    AppDelegate::setResourceVersion(_newResourceVersion);
                }
                goNext();
            }
        }
    }
}

std::string InstallLayerDolphin::getDownSizeShowString(cu_uint64 totalSize, cu_uint64 nowSize)
{
    if (totalSize == 0)
    {
        return "[-/-]";
    }
    else if (totalSize < 1024 * 1024)
    {
        float tl = (float)(totalSize) / 1024;
        float ns = (float)(nowSize) / 1024;
        return StringUtils::format("[%.2fKB/%.2fKB]", ns, tl);
    }
    else
    {
        float tl = (float)(totalSize) / (1024 * 1024);
        float ns = (float)(nowSize) / (1024 * 1024);
        return StringUtils::format("[%.2fMB/%.2fMB]", ns, tl);
    }
}

void InstallLayerDolphin::OnDolphinVersionInfo(dolphinVersionInfo& info)
{
    cocos2d::log("===>InstallLayerDolphin OnDolphinVersionInfo isNeedUpdating:%d",info.isNeedUpdating?1:0);
    
    if(_shouldStop)
        return ;

    _isStartUpdate = true;
    
    if(info.isNeedUpdating ){
        if (_isGrayUpdate)
        {
            EventCustom grayUpdateEvent("GRAY_UPDATE_COMPLETE");
            std::string retStr = "update";
            grayUpdateEvent.setUserStr(retStr);
            Director::getInstance()->getEventDispatcher()->dispatchEvent(&grayUpdateEvent);
        }
        
        _waitNewVersion = true;
        std::string verStr = StringUtils::format("%d.%d.%d.%d",info.versionNumberOne,info.versionNumberTwo,info.versionNumberThree,info.versionNumberFour);
        if (_currentUpdateType == GCloud::UpdateInitType_OnlySource){
            _newResourceVersion = StringUtils::format("%d", info.versionNumberFour);
            // 有资源更新
            AppDelegate::gsdkSetEvent(1, true, "2-sucess", false, false);
        }else{
            // 有包更新
            AppDelegate::gsdkSetEvent(1, true, "1-sucess", false, false);
            #if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
            
                _iosAppDownloadUrl = (char *)info.userDefineStr;
                MessageDialog* dialog = MessageDialog::create();
                if (dialog != nullptr)
                {
                    
                    if(!info.isForcedUpdating){
                        std::string content = StringUtils::format("获取到新App版本(%d.%d.%d)，请尽快前往更新! ", info.versionNumberOne,info.versionNumberTwo,info.versionNumberThree);
                        dialog->setMessage(content.c_str());
                        dialog->setTwoButton(true);
                        dialog->setCancelButtonStr("下次再说");
                        dialog->setConfirmButton("前往下载");
                        dialog->setCancelCallback([this](MessageDialog* sender){
                            this->stopUpdate();
                            sender->removeFromParent();
                            scheduleOnce([this](float){
                                this->goNext();
                            },0,"goNext");
                        });
                        dialog->setConfirmCallback([this](MessageDialog* sender){
                            this->stopUpdate();
                            sender->removeFromParent();
                            cocos2d::log("===========>> iosAppDownloadUrl: %s", this->_iosAppDownloadUrl.c_str());
                            if(_iosAppDownloadUrl != ""){
                                Application::getInstance()->openURL( this->_iosAppDownloadUrl);
                            }
                        });
                    }else{
                        std::string content = StringUtils::format("获取到新App版本(%d.%d.%d)，请前往更新！", info.versionNumberOne,info.versionNumberTwo,info.versionNumberThree);
                        dialog->setMessage(content.c_str());
                        dialog->setTwoButton(false);
                        dialog->setConfirmButton("前往下载");
                        dialog->setConfirmCallback([this](MessageDialog* sender){
                            this->stopUpdate();
//                            sender->removeFromParent();
                            cocos2d::log("===========>> iosAppDownloadUrl: %s", this->_iosAppDownloadUrl.c_str());
                            if(_iosAppDownloadUrl != ""){
                                Application::getInstance()->openURL( this->_iosAppDownloadUrl);
                            }
                        });
                    }
                    this->addChild(dialog);
                }
                return;
            #endif
           
        }
        
        std::string content = StringUtils::format("获取到新版本(%s),需要的下载大小是%.2fM",verStr.c_str(),info.needDownloadSize/1024.0f/1024.0f);
        
        if(info.isForcedUpdating){
            MessageDialog* dialog = MessageDialog::create();
            if (dialog != nullptr)
            {
                dialog->setMessage(content.c_str());
                dialog->setConfirmCallback([this](MessageDialog* sender){
                    continueUpdate();
                    sender->removeFromParent();
                });
                
                this->addChild(dialog);
            }
        }else{
            ConfirmBox* confirmBox = ConfirmBox::create();
            confirmBox->setMessage(content.c_str());
            confirmBox->setConfirmCallback([this](ConfirmBox* sender){
                //注意这里如果先removeFromParent()会触发ConfirmBox的析构函数导致lambda被释放导致this指针变成野指针,坑啊！！！
                continueUpdate();
                sender->removeFromParent();
            });
            confirmBox->setCancelCallback([this](ConfirmBox* sender){
                _updateSuccess = true;
                _waitNewVersion = false;
                if(_currentUpdateType == GCloud::UpdateInitType_OnlySource){
                    _newResourceVersion = "";
                }
                sender->removeFromParent();
            });
            this->addChild(confirmBox);
        }
    }
    else{
        _updateSuccess = true;
        if(_currentUpdateType == GCloud::UpdateInitType_OnlySource){
            AppDelegate::gsdkSetEvent(1, true, "2-sucess", false, false);
            AppDelegate::gsdkSetEvent(2, true, "2-sucess", false, false);
        }else{
            AppDelegate::gsdkSetEvent(1, true, "1-sucess", false, false);
            AppDelegate::gsdkSetEvent(2, true, "1-sucess", false, false);
        }
    }
}

void InstallLayerDolphin::OnDolphinProgress(dolphinUpdateStage curVersionStage, cu_uint64 totalSize, cu_uint64 nowSize)
{
    // cocos2d::log("===>OnDolphinProgress curVersionStage:%d totalSize:%llu nowSize:%llu",(int)curVersionStage,totalSize,nowSize);
    
    if(_shouldStop)
        return ;
    
    bool isVersionStageChange = false;
    if (curVersionStage != _curVersionStage)
    {
        cocos2d::log("===>OnDolphinProgress curVersionStage:%d preVersionStage:%d", curVersionStage, _curVersionStage);
        isVersionStageChange = true;
        _curVersionStage = curVersionStage;
        _speedCounter.stopSpeedCounter();
    }

    bool isDownloading = false;
    std::string msg = _dolphinInfoString.GetUpdateInfoString(curVersionStage,_currentUpdateType,isDownloading);
    
    if (isVersionStageChange && isDownloading)
        _speedCounter.startSpeedCounter();

    if (nowSize <= totalSize && totalSize > 0)
    {
        int p = static_cast<int>((float)nowSize/totalSize*100.0f);
        if (isDownloading)
        {
            msg = msg + " " + getDownSizeShowString(totalSize, nowSize);
            _speedCounter.setSize((uint)nowSize);
            updateProgressLabel(StringUtils::format("%d%%(%.1fKB/s)",p,_speedCounter.getSpeed()/1024.0f));
        }
        else{
            updateProgressLabel(StringUtils::format("%d%%",p));
        }
        updateProgressBar(p);
    }else{
        updateProgressBar(0);
    }
    
    updateStageLabel(msg);
}

void InstallLayerDolphin::OnDolphinError(dolphinUpdateStage curVersionStage, cu_uint32 errorCode)
{
    if(_shouldStop)
        return ;
    
    if (_isGrayUpdate)
    {
        EventCustom grayUpdateEvent("GRAY_UPDATE_COMPLETE");
        std::string retStr = "update";
        grayUpdateEvent.setUserStr(retStr);
        Director::getInstance()->getEventDispatcher()->dispatchEvent(&grayUpdateEvent);
    }
    
    cocos2d::log("===>InstallLayerDolphin OnDolphinError %d code:%u",curVersionStage,errorCode);
    _lastErrorCode = errorCode;
    _lastErrorStage = curVersionStage;
    if(_lastErrorCode != kSuccess)
    {
        std::string errorStr = _dolphinErrorString.getUpdateErrorString((GCloud::EErrorCode)_lastErrorCode);
        MessageDialog* dialog = MessageDialog::create();
        if (dialog != nullptr)
        {
            dialog->setMessage(errorStr.c_str());
            dialog->setConfirmButton("点击重试");
            dialog->setConfirmCallback([this](MessageDialog* sender){
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
                AppDelegate::restartApp();
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
                // Exit app.
                Director::getInstance()->end();
                exit(0);
#endif
                sender->removeFromParent();
            });
            
            this->addChild(dialog);
        }
        _waitMessageBox = true;
        _waitNewVersion = false;
    }
    
    if(_isStartUpdate){
        // 资源/包 更新失败
        const char *s = _currentUpdateType == GCloud::UpdateInitType_OnlySource? "2-" : "1-";
        char *buf = new char[strlen(s) + sizeof(errorCode) + 1];
        sprintf(buf, "%s%d", s, errorCode);
        AppDelegate::gsdkSetEvent(2, false, buf, false, false);
    }else{
        // 检测更新失败
        char *buf = new char[sizeof(errorCode) + 1];
        sprintf(buf, "%d", errorCode);
        AppDelegate::gsdkSetEvent(1, false, buf, false, false);
    }
    
}

void InstallLayerDolphin::OnDolphinSuccess()
{
    if(_shouldStop)
        return ;
    
    cocos2d::log("===>InstallLayerDolphin OnDolphinSuccess");
    
    _updateSuccess = true;
    _lastErrorCode = kSuccess;
    updateStageLabel("更新成功");
    
    // 资源/包 更新成功
    const char* msg = _currentUpdateType == GCloud::UpdateInitType_OnlySource ? "2-sucess" : "1-sucess";
    AppDelegate::gsdkSetEvent(2, true, msg, false, false);
}

void InstallLayerDolphin::OnDolphinNoticeInstallApk(char* apkurl)
{
    if(_shouldStop)
        return ;
    
    cocos2d::log("===>InstallLayerDolphin OnDolphinNoticeInstallApk %s",apkurl);
    
    updateStageLabel("正在安装更新包");
    
#if CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID
    JniMethodInfo t;
    
    if (JniHelper::getStaticMethodInfo(t, "com/repong/framework/ChannelAPI", "installApk", "(Ljava/lang/String;)V")) {
        jstring stringArg1 = t.env->NewStringUTF(apkurl);
        t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg1);
        
        t.env->DeleteLocalRef(t.classID);
        t.env->DeleteLocalRef(stringArg1);
    }
    AppDelegate::closeApp();
#else
    Application::getInstance()->openURL(apkurl);
#endif
}

void InstallLayerDolphin::OnDolphinFirstExtractSuccess()
{
    if(_shouldStop)
        return ;
    cocos2d::log("===>InstallLayerDolphin OnDolphinFirstExtractSuccess");
    
    _needFirstExtract = false;
    _needReloadString = true;
    
    auto userDefault = UserDefault::getInstance();
    // auto application = Application::getInstance();
    // std::string resVersion = application->getVersion()+".1."+application->getVersionCode();
    // userDefault->setStringForKey(UD_RES_VERSION, resVersion);
    userDefault->setIntegerForKey(UD_FIRST_EXTRACT,1);
    userDefault->flush();

    // 解压成功再次加载新的用户配置，重新开始热更新
    // if(FileUtils::getInstance()->isFileExist("config_user.plist"))
    // {
    //     cocos2d::log("===>InstallLayerDolphin reload config_user.plist");
    //     Configuration::getInstance()->loadConfigFile("config_user.plist");
    // }
    // unscheduleUpdate();
    // uninitDolphin();
    // goStart();
}

#endif



void InstallLayerDolphin::goNext()
{
    cocos2d::log("===>InstallLayerDolphin::goNext");
#ifdef USE_GCLOUD
    unscheduleUpdate();
    
    uninitDolphin();

    if(_needFirstExtract){
        auto userDefault = UserDefault::getInstance();
        userDefault->setIntegerForKey(UD_FIRST_EXTRACT,1);
        userDefault->flush();
    }
#endif
    
    bool needReload = (_needReloadString || _newResourceVersion.size()>0);
    if(needReload)
    {
        cocos2d::log("===>InstallLayerDolphin::needReload");
        _needReloadString = false;
        _newResourceVersion = "";

        //坑啊一定注意 当资源发生变化一定要清除文件缓存
        FileUtils::getInstance()->purgeCachedEntries();
    }
    
#ifdef USE_GCLOUD
    if (_isGrayUpdate)
    {
        EventCustom grayUpdateEvent("GRAY_UPDATE_COMPLETE");
        std::string retStr = needReload ? "reload" : "comp";
        grayUpdateEvent.setUserStr(retStr);
        Director::getInstance()->getEventDispatcher()->dispatchEvent(&grayUpdateEvent);
    }else{
        if (needReload)
        {
            AppDelegate::relaunchApp(true);
        }else{
            runMainLua();
#ifdef USE_MSDK
#if CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID
            safeapi::SafeAPI::getInstance()->onUpdateFinish();
#endif
#endif
        }
    }
#else
    runMainLua();
#ifdef USE_MSDK
#if CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID
        safeapi::SafeAPI::getInstance()->onUpdateFinish();
#endif
#endif

#endif
}


